﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SpotifyLync.Forms
{
    public partial class ProfanityFilter : Form
    {
        // Textbox Hint.
        private const string ADDWORD_HINT = "Enter Filter Word";

        /// <summary>
        /// Creates a new instance of the form.
        /// </summary>
        public ProfanityFilter()
        {
            InitializeComponent();
            InitializeAddWordTextBox();
            LoadWords();
        }

        /// <summary>
        /// Handles the cancel button click.  Makes a friendly exit.
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void CancelButton_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.Close();
        }

        /// <summary>
        /// Handles the event for the selected index change of the word list.  This
        /// enables or disables the <see cref="RemoveButton"/>
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void WordList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (WordList.SelectedIndices.Count > 0)
            {
                RemoveButton.Enabled = true;
            }
            else
            {
                RemoveButton.Enabled = false;
            }
        }
        
        /// <summary>
        /// Handles the event for the text change in the word box.  This enables or 
        /// disables the <see cref="AddWordButton"/>
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void AddWord_TextChanged(object sender, EventArgs e)
        {
            if ((AddWord.Text.Length > 0) && (AddWord.Text != ADDWORD_HINT))
            {
                AddWordButton.Enabled = true;
            }
            else
            {
                AddWordButton.Enabled = false;
            }
        }

        #region AddWord Textbox Voodoo
        
        /// <summary>
        /// Handles the behavior when a user clicks or tabs into the AddWord textbox.
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void AddWord_Enter(object sender, EventArgs e)
        {
            AddWord.ForeColor = Color.Black;
            if (AddWord.Text == ADDWORD_HINT)
            {
                AddWord.Clear();
            }
        }

        /// <summary>
        /// Handles the behavior when a user clicks or tabs out of the AddWord textbox.
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void AddWord_Leave(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(AddWord.Text))
            {
                InitializeAddWordTextBox();
            }
        }

        /// <summary>
        /// Defaults the AddWord TextBox to show a hint.
        /// </summary>
        private void InitializeAddWordTextBox()
        {
            AddWord.ForeColor = Color.Gray;
            AddWord.Text = ADDWORD_HINT;
        }

        #endregion

        #region Data and File Interactions

        /// <summary>
        /// Adds the user entered word to the list.
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void AddWordButton_Click(object sender, EventArgs e)
        {
            int itemCount = (from string o in WordList.Items
                         where (o == AddWord.Text)
                         select o).Count();

            if (itemCount < 1)
            {
                WordList.Items.Add(AddWord.Text);
                ClearDisplayMessage();
                AddWord.Text = String.Empty;
            }
            else
            {
                SetDisplayMessage(true, "That word exists in the list already.");
            }
        }

        /// <summary>
        /// Removes words from the list.
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void RemoveButton_Click(object sender, EventArgs e)
        {
            // Go through in reverse order and remove the words.
            for (int i = WordList.SelectedIndices.Count - 1; i > -1; i--)
            {
                int index = WordList.SelectedIndices[i];
                WordList.Items.RemoveAt(index);
            }
        }

        /// <summary>
        /// Handles the event for the click of the OK button, which saves the file.
        /// </summary>
        /// <param name="sender">The object invoking this event.</param>
        /// <param name="e">An object conatining any event arguments for this event.</param>
        private void OkButton_Click(object sender, EventArgs e)
        {

            StringBuilder listBuilder = new StringBuilder();

            // Jump through and get the words.
            foreach(object s in WordList.Items)
            {
                // File must take the form of word1|word2|word3 where there is a pipe
                // at neither the beginning nor the end.
                if(listBuilder.Length > 0) { listBuilder.Append("|"); }
                listBuilder.Append(s);
            }

            // write it out.
            using (StreamWriter writer = new StreamWriter(
                    Application.StartupPath + "\\Resources\\bad-words.txt"))
            { 
                writer.Write(listBuilder.ToString());       
            }

            // Friendly Exit.
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }

        /// <summary>
        /// Loads the list of "bad words" from the file.
        /// </summary>
        private void LoadWords()
        {
            string badWords = string.Empty;
            using (Stream stream = new FileStream(
                    Application.StartupPath + "\\Resources\\bad-words.txt", FileMode.Open))
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    badWords = reader.ReadToEnd();
                }
            }

            // Words are stored as pipe separated.
            string[] words = badWords.Split('|');
            WordList.Items.AddRange(words);
        }
        
        #endregion

        private void SetDisplayMessage(bool isError, string message)
        {
            if (isError)
            {
                MessageDisplay.ForeColor = Color.Red;
                MessageDisplay.Text = message;
            }
        }

        private void ClearDisplayMessage()
        {

            MessageDisplay.Text = String.Empty;
            MessageDisplay.ForeColor = Color.Black;
        }

    }
}
